home *** CD-ROM | disk | FTP | other *** search
/ Scene Storm / Scene Storm - Volume 1.iso / coding / c / vbcc / ic.c < prev    next >
C/C++ Source or Header  |  1995-11-23  |  32KB  |  927 lines

  1. #include "vbc.h"
  2.  
  3. struct IC *first_ic=0,*last_ic=0;
  4. int float_used;
  5.  
  6. int do_arith(np,struct IC *,np,struct obj *);
  7.  
  8. void add_IC(struct IC *new)
  9. /*  fuegt ein IC ein                                            */
  10. {
  11.     int code;
  12.     if(!new) return;
  13.     if(nocode) {free(new);return;}
  14.     new->next=0;
  15.     new->q1.am=new->q2.am=new->z.am=0;
  16.     code=new->code;
  17.     if(code>=BEQ&&code<=BRA) new->q1.flags=new->q2.flags=new->z.flags=0;
  18.     if(code==ALLOCREG||code==FREEREG||code==SAVEREGS||code==RESTOREREGS) new->typf=0;
  19.     if(DEBUG&64) pric2(stdout,new);
  20.     if(new->q1.flags&VAR){
  21.         if(!new->q1.v) ierror(0);
  22.         new->q1.v->flags|=USEDASSOURCE;
  23.         if(code==ADDRESS||(new->q1.flags&VARADR)) new->q1.v->flags|=USEDASADR;
  24.         new->q1.v->priority+=currentpri;
  25.     }
  26.     if(new->q2.flags&VAR){
  27.         if(!new->q2.v) ierror(0);
  28.         new->q2.v->flags|=USEDASSOURCE;
  29.         if(code==ADDRESS||(new->q2.flags&VARADR)) new->q2.v->flags|=USEDASADR;
  30.         new->q2.v->priority+=currentpri;
  31.     }
  32.     if(new->z.flags&VAR){
  33.         if(!new->z.v) ierror(0);
  34.         if(new->z.flags&DREFOBJ) new->z.v->flags|=USEDASSOURCE; else new->z.v->flags|=USEDASDEST;
  35.         new->z.v->priority+=currentpri;
  36.     }
  37.     if(/*(c_flags_val[0].l&2)&&*/code==LABEL){
  38.     /*  entfernt Spruenge zu direkt folgenden Labels    */
  39.         struct IC *p=last_ic;
  40.         while(p){
  41.             if(p->typf==new->typf&&p->code>=BEQ&&p->code<=BRA){
  42.                 remove_IC(p);
  43.                 if(DEBUG&1) printf("%s l%d deleted\n",ename[p->code],p->typf);
  44.             }else{
  45.                 if(p->code!=LABEL) break;
  46.             }
  47.             p=p->prev;
  48.         }
  49.     }
  50.     if(last_ic){
  51. /*    if(c_flags_val[0].l&2){*/
  52.         if(code==ASSIGN){
  53.             if((last_ic->z.flags&(REG|SCRATCH|DREFOBJ))==(REG|SCRATCH)&&(new->q1.flags==last_ic->z.flags)&&last_ic->z.reg==new->q1.reg&&last_ic->code!=CALL){
  54.                 if(USEQ2ASZ||!(last_ic->q2.flags®)||!(new->z.flags®)||last_ic->q2.reg!=new->z.reg){
  55.                     if(USEQ2ASZ||!(last_ic->q2.flags&VAR)||!(new->z.flags&VAR)||last_ic->q2.v!=new->z.v){
  56.                     /*  verbindet op a,b->reg,move reg->c zu op a,b->c  */
  57.                     /*  hier fehlt aber noch Registerfreigabe           */
  58.                         last_ic->z=new->z;
  59.                         if(DEBUG&1) printf("move and op combined\n");
  60.                         if((new->q1.flags&SCRATCH)&&(new->q1.reg!=new->z.reg||!(new->z.flags®)))
  61.                             free_reg(new->q1.reg);
  62.                         free(new);
  63.                         return;
  64.                     }
  65.                 }
  66.             }
  67.         }
  68.         if(last_ic->code==BRA){
  69.             if(code!=LABEL&&code!=ALLOCREG&&code!=FREEREG){
  70.             /*  loescht alles nach bra bis ein Label kommt  */
  71.             /*  momentan noch nicht perfekt, da es bei alloc/freereg stoppt */
  72.                 free(new);
  73.                 if(DEBUG&1) printf("Unreachable Statement deleted\n");
  74.                 return;
  75.             }
  76.             if(last_ic->prev&&code==LABEL){
  77.             /*  ersetzt bcc l1;bra l2;l1 durch b!cc l2      */
  78.                 if(last_ic->prev->code>=BEQ&&last_ic->prev->code<=BGT&&new->typf==last_ic->prev->typf){
  79.                     if(DEBUG&1) printf("%s l%d;%s l%d; substituted\n",ename[last_ic->prev->code],last_ic->prev->typf,ename[last_ic->code],last_ic->typf);
  80.                     if(last_ic->prev->code&1) last_ic->prev->code--;
  81.                                     else      last_ic->prev->code++;
  82.                     last_ic->prev->typf=last_ic->typf;
  83.                     last_ic=last_ic->prev;
  84.                     free(last_ic->next);
  85.                     last_ic->next=new;new->prev=last_ic;
  86.                     last_ic=new;
  87.                     return;
  88.                 }
  89.             }
  90.         }
  91. /*        }*/
  92.         new->prev=last_ic;
  93.         last_ic->next=new;
  94.         last_ic=new;
  95.     }else{
  96.         last_ic=new;first_ic=new;new->prev=0;
  97.     }
  98.     /*  Merken, on Fliesskomma benutzt wurde    */
  99.     if(code!=LABEL&&(code<BEQ||code>BRA))
  100.         if((new->typf&15)==FLOAT||(new->typf&15)==DOUBLE) float_used=1;
  101.     if((new->q1.flags&SCRATCH)&&(new->q1.reg!=new->z.reg||!(new->z.flags®)))
  102.         free_reg(new->q1.reg);
  103.     if((new->q2.flags&SCRATCH)&&(new->q2.reg!=new->z.reg||!(new->z.flags®)))
  104.         free_reg(new->q2.reg);
  105. }
  106. void free_IC(struct IC *p)
  107. /*  Gibt IC-Liste inkl. Typen frei                  */
  108. {
  109.     struct IC *merk;
  110.     while(p){
  111.         if(!(c_flags_val[0].l&128)){
  112.             if(p->q1.am||p->q2.am||p->z.am)
  113.                 {p->q1.am=p->q2.am=p->z.am=0;ierror(0);}
  114.         }else{
  115.             if(p->q1.am) free(p->q1.am);
  116.             if(p->q2.am) free(p->q2.am);
  117.             if(p->z.am) free(p->z.am);
  118.         }
  119.         merk=p->next;
  120.         free(p);
  121.         p=merk;
  122.     }
  123. }
  124. void gen_IC(np p,int ltrue,int lfalse)
  125. /*  Erzeugt eine IC-Liste aus einer expression      */
  126. {
  127.     struct IC *new;
  128.     if(!p) return;
  129.     if(p->flags==STRING){
  130.     /*  hier fehlt noch die Verwaltung der String-Inhalte   */
  131.         p->o.v=add_var(empty,clone_typ(p->ntyp),STATIC,(struct const_list *)p->identifier);
  132.         p->o.v->flags|=DEFINED;
  133.         p->o.flags=VAR;
  134.         p->o.reg=0;
  135.         p->o.val=p->val;
  136.         return;
  137.     }
  138.     if(p->flags==IDENTIFIER){
  139.         p->o.v=find_var(p->identifier,0);
  140.         p->o.flags=VAR;
  141.         p->o.reg=0;
  142.         p->o.val=p->val;
  143.         return;
  144.     }
  145.     if(p->flags==CEXPR||p->flags==PCEXPR){
  146.         if(p->left){
  147.             if(p->left->flags==POSTINC) p->left->flags=PREINC;
  148.             if(p->left->flags==POSTDEC) p->left->flags=PREDEC;
  149.             gen_IC(p->left,0,0);
  150.             if(p->left->o.flags&SCRATCH) free_reg(p->left->o.reg);
  151.         }
  152.         if(p->right){
  153.             if(p->right->flags==POSTINC) p->right->flags=PREINC;
  154.             if(p->right->flags==POSTDEC) p->right->flags=PREDEC;
  155.             gen_IC(p->right,0,0);
  156.             if(p->right->o.flags&SCRATCH) free_reg(p->right->o.reg);
  157.         }
  158.         p->o.flags=KONST;
  159.         p->o.val=p->val;
  160.         p->o.reg=0;
  161.         return;
  162.     }
  163.     if(p->flags==KOMMA){
  164.         if(p->left->sidefx){
  165.             gen_IC(p->left,0,0);
  166.             if(p->left->o.flags&SCRATCH) free_reg(p->left->o.reg);
  167.         } else error(129);
  168.         gen_IC(p->right,0,0);
  169.         p->o=p->right->o;
  170.         return;
  171.     }
  172.     if(p->flags==CAST){
  173.         gen_IC(p->left,0,0);
  174.         convert(p->left,p->ntyp->flags&31);
  175.         p->o=p->left->o;
  176.         return;
  177.     }
  178.     if(p->flags==FIRSTELEMENT){
  179.         gen_IC(p->left,0,0);
  180.         p->o=p->left->o;
  181.         return;
  182.     }
  183.     new=(struct IC *)mymalloc(ICS);
  184.     new->typf=p->ntyp->flags&31;
  185.     new->q1.reg=new->q2.reg=new->z.reg=0;
  186.     new->q1.flags=new->q2.flags=new->z.flags=0;
  187.     if((p->flags>=LSHIFT&&p->flags<=MOD)||(p->flags>=OR&&p->flags<=AND)||p->flags==PMULT){
  188.         do_arith(p,new,0,0);
  189.         return;
  190.     }
  191.     if(p->flags==CONTENT){
  192.         gen_IC(p->left,0,0);
  193.         if(p->left->o.flags&VARADR){
  194.             free(new);
  195.             p->o=p->left->o;
  196.             p->o.flags&=~VARADR;
  197.             return;
  198.         }
  199.         if(!(p->left->o.flags&DREFOBJ)){
  200.             free(new);
  201.             p->o=p->left->o;
  202.             p->o.flags|=DREFOBJ;
  203.             return;
  204.         }
  205.         if(p->left->o.flags&SCRATCH){
  206.             new->z=p->left->o;
  207.             new->z.flags&=~DREFOBJ;
  208.         }else{
  209.             /*  hier muss man noch was aender, da das so nicht funktioniert */
  210.             get_scratch(&new->z,p->left->ntyp->flags,p->ntyp->flags);
  211.         }
  212.         new->code=ASSIGN;new->typf=POINTER;
  213.         new->q1=p->left->o;
  214.         new->q2.reg=sizetab[POINTER];
  215.         add_IC(new);
  216.         p->o=new->z;
  217.         p->o.flags|=DREFOBJ;
  218.         return;
  219.     }
  220.     if(p->flags==ASSIGN){
  221.         new->code=ASSIGN;
  222.         gen_IC(p->right,0,0);
  223.         gen_IC(p->left,0,0);
  224.         convert(p->right,p->ntyp->flags&31);
  225.         new->q1=p->right->o;
  226.         new->z=p->left->o;
  227.         new->q2.reg=szof(p->left->ntyp);
  228.         add_IC(new);
  229.         p->o=new->z;
  230.         return;
  231.     }
  232.     if(p->flags==ASSIGNADD){
  233.     /*  das hier ist nicht besonders schoen */
  234.         struct obj o;struct IC *n;int f;
  235.         if(p->right->right==0){
  236.         /*  sowas wie a+=0 wurde wegoptimiert   */
  237.             free(new);
  238.             p->o=p->left->o;
  239.             return;
  240.         }
  241.         f=do_arith(p->right,new,p->left,&o);
  242.         if(!f) {ierror(0);return;}
  243.         if(f>1) {ierror(0);return;}
  244.         if(!nocode&&(o.flags&(SCRATCH|REG))==(SCRATCH|REG)&&!regs[o.reg]){
  245.         /*  ueberfluessiges FREEREG entfernen   */
  246.             n=last_ic;
  247.             while(n){
  248.                 if(n->code==FREEREG&&n->q1.reg==o.reg){
  249.                     remove_IC(n);if(!nocode) regs[o.reg]=1;
  250.                     break;
  251.                 }
  252.                 n=n->prev;
  253.             }
  254.         }
  255.         convert(p->right,p->ntyp->flags&31);
  256.         new=(struct IC *)mymalloc(ICS);
  257.         new->typf=p->ntyp->flags&31;
  258.         new->q2.flags=0;
  259.         new->code=ASSIGN;
  260.         new->q1=p->right->o;
  261.         new->z=o;
  262.         new->q2.reg=szof(p->left->ntyp);
  263.         add_IC(new);
  264.         p->o=new->z;
  265.         return;
  266.     }
  267.     if(p->flags==MINUS||p->flags==KOMPLEMENT){
  268.         new->code=p->flags;
  269.         gen_IC(p->left,0,0);
  270.         convert(p->left,p->ntyp->flags);
  271.         if(regok(p->left->o.reg,p->ntyp->flags,0)&&(p->left->o.flags&SCRATCH)){
  272.             new->z=p->left->o;
  273.             new->z.flags&=~DREFOBJ;
  274.         }else{
  275.             get_scratch(&new->z,p->left->ntyp->flags,0);
  276.         }
  277.         new->q1=p->left->o;
  278.         add_IC(new);
  279.         p->o=new->z;
  280.         return;
  281.     }
  282.     if(p->flags==ADDRESS||p->flags==ADDRESSA||p->flags==ADDRESSS){
  283.         new->code=ADDRESS;
  284.         new->typf=p->left->ntyp->flags&31;
  285.         gen_IC(p->left,0,0);
  286.         if(p->left->o.flags&VAR) p->left->o.v->flags|=USEDASSOURCE|USEDASDEST;
  287.         if(p->left->o.flags&DREFOBJ){
  288.             free(new);
  289.             p->o=p->left->o;
  290.             p->o.flags&=~DREFOBJ;
  291.             return;
  292.         }
  293.         if((p->left->o.flags&VAR)&&!(p->left->o.flags&VARADR)
  294.            &&(p->left->o.v->storage_class==EXTERN||p->left->o.v->storage_class==STATIC)){
  295.             free(new);
  296.             p->o=p->left->o;
  297.             p->o.flags|=VARADR;
  298.             return;
  299.         }
  300.         new->q1=p->left->o;
  301.         get_scratch(&new->z,POINTER,p->ntyp->next->flags);
  302.         add_IC(new);
  303.         p->o=new->z;
  304.         return;
  305.     }
  306.     if(p->flags==LAND||p->flags==LOR){
  307.         int l1,l2,l3,l4;
  308. /*        printf("%s true=%d false=%d\n",ename[p->flags],ltrue,lfalse);*/
  309.         l1=++label;if(!ltrue) {l2=++label;l3=++label;l4=++label;}
  310.         if(!ltrue){if(p->flags==LAND) gen_IC(p->left,l1,l3);
  311.                     else gen_IC(p->left,l3,l1);
  312.         }else     {if(p->flags==LAND) gen_IC(p->left,l1,lfalse);
  313.                     else gen_IC(p->left,ltrue,l1);
  314.         }
  315.         if(p->left->o.flags!=0){
  316.             new->code=TEST;
  317.             new->q2.flags=new->z.flags=0;
  318.             new->typf=p->left->ntyp->flags&31;
  319.             new->q1=p->left->o;
  320.             add_IC(new);
  321.             new=(struct IC *)mymalloc(ICS);
  322.             if(p->flags==LAND) new->code=BEQ; else new->code=BNE;
  323.             if(!ltrue) new->typf=l3;
  324.             else{if(p->flags==LAND) new->typf=lfalse; else new->typf=ltrue;}
  325.             add_IC(new);
  326.         }
  327.         gen_label(l1);
  328.         if(!ltrue){if(p->flags==LAND) gen_IC(p->right,l2,l3);
  329.                     else gen_IC(p->right,l3,l2);
  330.         }else      gen_IC(p->right,ltrue,lfalse);
  331.         if(p->right->o.flags!=0){
  332.             new=(struct IC *)mymalloc(ICS);
  333.             new->code=TEST;
  334.             new->q2.flags=new->z.flags=0;
  335.             new->typf=p->right->ntyp->flags&31;
  336.             new->q1=p->right->o;
  337.             add_IC(new);
  338.             new=(struct IC *)mymalloc(ICS);
  339.             if(p->flags==LAND) new->code=BEQ; else new->code=BNE;
  340.             if(!ltrue) new->typf=l3;
  341.             else{if(p->flags==LAND) new->typf=lfalse; else new->typf=ltrue;}
  342.             add_IC(new);
  343.         }
  344.         if(!ltrue){
  345.             gen_label(l2);
  346.             if(p->flags==LAND) p->o=gen_cond(0,l3,l4); else p->o=gen_cond(1,l3,l4);
  347.         }else{
  348.             new=(struct IC *)mymalloc(ICS);
  349.             new->code=BRA;
  350.             if(p->flags==LAND) new->typf=ltrue; else new->typf=lfalse;
  351.             add_IC(new);
  352.         }
  353.         if(ltrue) p->o.flags=0;
  354.         return;
  355.     }
  356.     if(p->flags==NEGATION){
  357.         int l1,l2,l3;
  358.         if(!ltrue) {l1=++label;l2=++label;l3=++label;}
  359.         if(ltrue) gen_IC(p->left,lfalse,ltrue); else gen_IC(p->left,l1,l3);
  360.         if(!p->left->o.flags) {free(new);p->o.flags=0;
  361.         }else{
  362.             new->code=TEST;
  363.             new->q2.flags=new->z.flags=0;
  364.             new->typf=p->left->ntyp->flags&31;
  365.             new->q1=p->left->o;
  366.             add_IC(new);
  367.             new=(struct IC *)mymalloc(ICS);
  368.             new->code=BNE;
  369.             if(!ltrue) new->typf=l1; else new->typf=lfalse;
  370.             add_IC(new);
  371.         }
  372.         if(ltrue){
  373.             new=(struct IC *)mymalloc(ICS);
  374.             new->code=BRA;
  375.             if(!ltrue) new->typf=l2; else new->typf=ltrue;
  376.             add_IC(new);
  377.             p->o.flags=0;
  378.         }else{
  379.             gen_label(l3);
  380.             p->o=gen_cond(0,l1,l2);
  381.         }
  382.         return;
  383.     }
  384.     if(p->flags>=EQUAL&&p->flags<=GREATEREQ){
  385.         int l1,l2,l3,tl,tr,swapped;
  386.         if(!ltrue) {l1=++label;l2=++label;l3=++label;}
  387.         if(p->left->flags==CEXPR){
  388.         /*  Konstanten nach rechts  */
  389.             np merk;merk=p->left;p->left=p->right;p->right=merk;
  390.             swapped=1;
  391.         }else swapped=0;
  392.         new->code=COMPARE;
  393.         tl=p->left->ntyp->flags&31;tr=p->right->ntyp->flags&31;
  394.         if(p->right->flags==CEXPR&&(tr&15)<FLOAT&&(tl&15)<FLOAT){
  395.             zlong null;int negativ;
  396.             eval_constn(p->right);
  397.             null=l2zl(0L);
  398.             if(zlleq(vlong,0)) negativ=1; else negativ=0;
  399.             if(tr&UNSIGNED) negativ=0;
  400.             if((!negativ||zlleq(t_min[tl],vlong))&&(negativ||zulleq(vulong,t_max[tl]))){
  401.                 convert(p->right,tl);
  402.                 tr=tl;
  403.             }
  404.         }
  405.         if(arith(tl)&&tl!=tr){
  406.             struct Typ *t;
  407.             t=arith_typ(p->left->ntyp,p->right->ntyp);
  408.             new->typf=t->flags&31;
  409.             freetyp(t);
  410.         }else{
  411.             new->typf=p->left->ntyp->flags&31;
  412.         }
  413.         gen_IC(p->left,0,0);
  414.         convert(p->left,new->typf);
  415.         gen_IC(p->right,0,0);
  416.         convert(p->right,new->typf);
  417.         new->q1=p->left->o;
  418.         new->q2=p->right->o;
  419.         new->z.flags=0;
  420.         add_IC(new);
  421.         new=(struct IC *)mymalloc(ICS);
  422.         if(p->flags==EQUAL) new->code=BEQ;
  423.         if(p->flags==INEQUAL) new->code=BNE;
  424.         if(p->flags==LESS) {if(swapped) new->code =BGT; else new->code=BLT;}
  425.         if(p->flags==LESSEQ){if(swapped) new->code=BGE; else new->code=BLE;}
  426.         if(p->flags==GREATER){if(swapped) new->code=BLT; else new->code=BGT;}
  427.         if(p->flags==GREATEREQ){if(swapped) new->code=BLE; else new->code=BGE;}
  428.         if(ltrue) new->typf=ltrue; else new->typf=l1;
  429.         add_IC(new);
  430.         if(ltrue){
  431.             new=(struct IC *)mymalloc(ICS);
  432.             new->code=BRA;
  433.             new->typf=lfalse;
  434.             add_IC(new);
  435.             p->o.flags=0;
  436.         }else{
  437.             gen_label(l3);
  438.             p->o=gen_cond(1,l1,l2);
  439.         }
  440.         return;
  441.     }
  442.     if(p->flags==CALL){
  443.         int r,regused,sz;
  444.         function_calls+=currentpri;
  445.         gen_IC(p->left,0,0);
  446.         if(!(p->left->o.flags&DREFOBJ)){
  447.             free(new);
  448.             p->o=p->left->o;
  449.             if(p->o.flags&VARADR) p->o.flags&=~VARADR;
  450.              else p->o.flags|=DREFOBJ;
  451.         }else{
  452.             if(p->left->o.flags&VARADR){
  453.                 free(new);
  454.                 p->o=p->left->o;
  455.                 p->o.flags&=~VARADR;
  456.             }else{
  457.                 if(p->left->o.flags&SCRATCH){
  458.                     new->z=p->left->o;
  459.                     new->z.flags&=~DREFOBJ;
  460.                 }else{
  461.                 /* das hier funktioniert vermutlich auch nicht  */
  462.                     get_scratch(&new->z,p->left->ntyp->flags,p->ntyp->flags);
  463.                 }
  464.                 new->code=ASSIGN;new->typf=POINTER;
  465.                 new->q1=p->left->o;
  466.                 new->q2.reg=sizetab[POINTER];
  467.                 new->q2.flags=0;
  468.                 add_IC(new);
  469.                 p->o=new->z;
  470.                 p->o.flags|=DREFOBJ;
  471.             }
  472.         }
  473. /*            p->left->o.flags-=DREFOBJ|VARADR; Was sollte das??    */
  474.         r=freturn(p->ntyp);
  475.         if(!r){
  476.             struct Typ *t=mymalloc(TYPS);
  477.             t->flags=POINTER;t->next=p->ntyp;
  478.             r=freturn(t);
  479.             free(t);
  480.         }
  481.         if(!r) ierror(0);
  482.         regused=regs[r];
  483.         new=(struct IC *)mymalloc(ICS);
  484.         new->code=SAVEREGS;
  485.         new->typf=0;
  486.         if((p->o.flags&(REG|SCRATCH))==(REG|SCRATCH)) new->q1.reg=p->o.reg;
  487.             else new->q1.reg=0;
  488.         new->q1.flags=new->q2.flags=new->z.flags=0;
  489.         add_IC(new);
  490.         sz=push_args(p->alist,p->left->ntyp->next->exact,0);
  491.         if(!regused){
  492.             if(!nocode) regs[r]=1;
  493.             new=(struct IC *)mymalloc(ICS);
  494.             new->code=ALLOCREG;
  495.             new->typf=0;
  496.             new->q1.flags=REG;
  497.             new->q1.reg=r;
  498.             new->q2.flags=new->z.flags=0;
  499.             add_IC(new);regused=0;
  500.         }
  501.         new=(struct IC *)mymalloc(ICS);
  502.         new->code=CALL;new->typf=FUNKT;
  503.         new->q1=p->o;new->q2.flags=0;
  504.         new->q2.reg=sz;
  505.         new->z.reg=r;
  506.         /*  hier noch Returnregister retten etc.        */
  507.         new->z.flags=REG;
  508.         if(!regused) new->z.flags|=SCRATCH;
  509.         add_IC(new);
  510.         p->o=new->z;
  511.         if(!freturn(p->ntyp)) p->o.flags|=DREFOBJ;
  512.         if(regused){
  513.             if((p->ntyp->flags&15)!=VOID){
  514.                 new=(struct IC *)mymalloc(ICS);
  515.                 new->code=ASSIGN;
  516.                 new->typf=p->ntyp->flags&31;
  517.                 new->q1=p->o;
  518.                 new->q2.reg=szof(p->ntyp);
  519.                 new->q2.flags=0;
  520.                 get_scratch(&new->z,p->ntyp->flags&31,0);
  521.                 add_IC(new);
  522.                 p->o=new->z;
  523.             }
  524.         }
  525.         new=(struct IC *)mymalloc(ICS);
  526.         new->code=RESTOREREGS;
  527.         new->typf=0;
  528.         if(p->o.flags®) new->q1.reg=p->o.reg; else new->q1.reg=0;
  529.         new->q1.flags=new->q2.flags=new->z.flags=0;
  530.         add_IC(new);
  531.         return;
  532.     }
  533.     if(p->flags>=PREINC&&p->flags<=POSTDEC){
  534.         struct obj o;
  535.         gen_IC(p->left,0,0);
  536.         if(p->flags==POSTINC||p->flags==POSTDEC){
  537.             new=(struct IC *)mymalloc(ICS);
  538.             new->code=ASSIGN;
  539.             new->typf=p->ntyp->flags&31;
  540.             new->q2.reg=sizetab[p->ntyp->flags&15];
  541.             new->q1=p->left->o;
  542.             new->q1.flags&=~SCRATCH;
  543.             get_scratch(&new->z,p->left->ntyp->flags&31,0);
  544.             new->q2.flags=0;
  545.             add_IC(new);
  546.             o=new->z;
  547.             new=(struct IC *)mymalloc(ICS);
  548.         }else o=p->left->o;
  549.         if((p->left->ntyp->flags&15)==POINTER){
  550.             if(p->flags==PREINC||p->flags==POSTINC) new->code=ADDI2P; else new->code=SUBIFP;
  551.             vlong=l2zl((long)szof(p->left->ntyp->next));
  552.             new->q2.val.vint=zl2zi(vlong);
  553.             new->typf=INT;
  554.             new->q1=p->left->o;
  555.             new->z=p->left->o;
  556.             new->q2.flags=KONST;
  557.             add_IC(new);
  558.         }else{
  559.             if(p->flags==PREINC||p->flags==POSTINC) new->code=ADD; else new->code=SUB;
  560.             new->typf=p->ntyp->flags&31;
  561.             new->q1=p->left->o;
  562.             new->z=p->left->o;
  563.             new->q2.flags=KONST;
  564.             vlong=l2zl(1L);vulong=zl2zul(vlong);vdouble=zl2zd(vlong);
  565.             if(new->typf==CHAR) new->q2.val.vchar=zl2zc(vlong);
  566.             if(new->typf==SHORT) new->q2.val.vshort=zl2zs(vlong);
  567.             if(new->typf==INT) new->q2.val.vint=zl2zi(vlong);
  568.             if(new->typf==LONG) new->q2.val.vlong=vlong;
  569.             if(new->typf==(UNSIGNED|CHAR)) new->q2.val.vuchar=zul2zuc(vulong);
  570.             if(new->typf==(UNSIGNED|SHORT)) new->q2.val.vushort=zul2zus(vulong);
  571.             if(new->typf==(UNSIGNED|INT)) new->q2.val.vuint=zul2zui(vulong);
  572.             if(new->typf==(UNSIGNED|LONG)) new->q2.val.vulong=vulong;
  573.             if(new->typf==DOUBLE) new->q2.val.vdouble=vdouble;
  574.             if(new->typf==FLOAT) new->q2.val.vfloat=zd2zf(vdouble);
  575.             add_IC(new);
  576.         }
  577.         if(p->flags==POSTINC||p->flags==POSTDEC){
  578.             if(p->left->o.flags&SCRATCH) free_reg(p->left->o.reg);
  579.         }
  580.         p->o=o;
  581.         return;
  582.     }
  583.     if(p->flags==COND){
  584.         int ltrue,lfalse,lout;
  585.         ltrue=++label;lfalse=++label;lout=++label;
  586.         gen_IC(p->left,ltrue,lfalse);
  587.         if(!p->left->o.flags){
  588.             free(new);
  589.         }else{
  590.             if(p->left->flags!=CEXPR){
  591.                 new->code=TEST;
  592.                 new->typf=p->left->ntyp->flags&31;
  593.                 new->q1=p->left->o;
  594.                 new->q2.flags=new->z.flags=0;
  595.                 add_IC(new);
  596.                 new=(struct IC *)mymalloc(ICS);
  597.                 new->code=BEQ;
  598.                 new->typf=lfalse;
  599.                 add_IC(new);
  600.             }else{
  601.                 eval_constn(p->left);
  602.                 if(zleq(vlong)&&zuleq(vulong)&&zdeq(vdouble)){
  603.                     gen_IC(p->right->right,0,0);
  604.                     p->o=p->right->right->o;
  605.                 }else{
  606.                     gen_IC(p->right->left,0,0);
  607.                     p->o=p->right->left->o;
  608.                 }
  609.                 return;
  610.             }
  611.         }
  612.         gen_label(ltrue);
  613.         gen_IC(p->right->left,0,0);
  614.         convert(p->right->left,p->ntyp->flags&31);
  615.         if(p->right->left->o.flags&SCRATCH){
  616.             p->o=p->right->left->o;
  617.         }else{
  618.             get_scratch(&p->o,p->ntyp->flags&31,0);
  619.             new=(struct IC *)mymalloc(ICS);
  620.             new->code=ASSIGN;
  621.             new->q1=p->right->left->o;
  622.             new->z=p->o;
  623.             new->q2.flags=0;
  624.             new->q2.reg=szof(p->ntyp);
  625.             new->typf=p->ntyp->flags&31;
  626.             add_IC(new);
  627.             p->o=new->z;
  628.         }
  629.         new=(struct IC *)mymalloc(ICS);
  630.         new->code=BRA;
  631.         new->typf=lout;
  632.         add_IC(new);
  633.         gen_label(lfalse);
  634.         gen_IC(p->right->right,0,0);
  635.         convert(p->right->right,p->ntyp->flags&31);
  636.         new=(struct IC *)mymalloc(ICS);
  637.         new->code=ASSIGN;
  638.         new->q1=p->right->right->o;
  639.         new->z=p->o;
  640.         new->q2.flags=0;
  641.         new->q2.reg=szof(p->ntyp);
  642.         new->typf=p->ntyp->flags&31;
  643.         add_IC(new);
  644.         gen_label(lout);
  645.         return;
  646.     }
  647.     printf("Operation: %d=%s\n",p->flags,ename[p->flags]);
  648.     ierror(0);
  649.     free(new);
  650.     p->o.flags=0;
  651. }
  652. int push_args(struct argument_list *al,struct struct_declaration *sd,int n)
  653. /*  Legt die Argumente eines Funktionsaufrufs in umgekehrter Reihenfolge    */
  654. /*  auf den Stack. Es wird Integer-Erweiterung vorgenommen und float wird   */
  655. /*  nach double konvertiert, falls kein Prototype da ist. Ausserdem werden  */
  656. /*  alle Argumente in ihrer Groesse aligned. Das ist evtl. nicht fuer jede  */
  657. /*  CPU ausreichend. Hier muss evtl. noch etwas getan werden.               */
  658. {
  659.     int of,t,sz;struct IC *new;
  660.     if(!al) return(0);
  661.     if(al->next) of=push_args(al->next,sd,n+1); else of=0;
  662.     if(!al->arg) {ierror(0);return(of);}
  663.     if(!sd) {ierror(0);return(of);}
  664.     gen_IC(al->arg,0,0);
  665.     if(n<sd->count){t=sd->sl[n].styp->flags&15;sz=szof(sd->sl[n].styp);}
  666.      else {t=al->arg->ntyp->flags&15;sz=szof(al->arg->ntyp);}
  667.     if(t>=CHAR&&t<=LONG) {t=int_erw(t);sz=sizetab[t&15];}
  668.     if(t==FLOAT&&n>=sd->count) {t=DOUBLE;sz=sizetab[t];}
  669.     convert(al->arg,t&31);
  670.     new=(struct IC *)mymalloc(ICS);
  671.     new->code=PUSH;
  672.     new->typf=t;
  673.     new->q1=al->arg->o;
  674.     new->q2.flags=new->z.flags=0;
  675.     new->q2.reg=((sz+maxalign-1)/maxalign)*maxalign;
  676.     add_IC(new);
  677.     return(of+sz);
  678. }
  679.  
  680. void convert(np p,int f)
  681. /*  konvertiert das Objekt in p->o in bestimmten Typ    */
  682. {
  683.     struct IC *new;
  684.     if((f&15)==VOID||(p->ntyp->flags&31)==f) return;
  685.     if(p->flags==CEXPR||p->flags==PCEXPR){
  686.         eval_constn(p);
  687.         p->ntyp->flags=f;
  688.         insert_const(p);
  689.         p->o.val=p->val;
  690.         return;
  691.     }
  692.     if(!must_convert(p,f)) return;
  693.     new=(struct IC *)mymalloc(ICS);
  694.     new->q1=p->o;
  695.     new->q2.flags=0;
  696.     new->code=CONVCHAR+(p->ntyp->flags&15)-CHAR;
  697.     if(p->ntyp->flags&UNSIGNED) new->code+=8;
  698.     new->typf=f;
  699.     if(!regok(p->o.reg,f,0)||!(p->o.flags&SCRATCH)){
  700.         get_scratch(&new->z,f,0);
  701.         add_IC(new);
  702.     }else{
  703.         new->z=p->o;new->z.flags&=~DREFOBJ;
  704.         add_IC(new);
  705.     }
  706.     p->o=new->z;
  707. }
  708.  
  709. int allocreg(int f,int mode)
  710. /*  Fordert Register fuer Typ f an                      */
  711. /*  evtl. maschinenabhaengig, aber hier fehlt noch viel */
  712. /*  z.B. Eintragen eines IC                             */
  713. {
  714.     int i;struct IC *new;
  715.     if(nocode) return(1);
  716.     for(i=1;i<=MAXR;i++){
  717.         if(!regs[i]&®ok(i,f,mode)){
  718.             if(DEBUG&16) printf("alocated %s\n",regnames[i]);
  719.             regs[i]=1;regused[i]++;
  720.             new=(struct IC *)mymalloc(ICS);
  721.             new->code=ALLOCREG;
  722.             new->typf=0;
  723.             new->q1.flags=REG;
  724.             new->q1.reg=i;
  725.             new->q2.flags=new->z.flags=0;
  726.             add_IC(new);
  727.             return(i);}
  728.     }
  729.     if(DEBUG&1) printf(">%sCouldn't allocate register for type %d\n",string,f);
  730.     return(0);
  731. }
  732. void free_reg(int r)
  733. /*  Gibt Register r frei                                */
  734. /*  Eintrag eines IC fehlt noch                         */
  735. {
  736.     struct IC *new;
  737.     if(!r||nocode) return;
  738.     if(regs[r]==0) {printf("Register %s:\n",regnames[r]);ierror(0);}
  739.     if(DEBUG&16) printf("freed %s\n",regnames[r]);
  740.     new=(struct IC *)mymalloc(ICS);
  741.     new->code=FREEREG;
  742.     new->typf=0;
  743.     new->q1.flags=REG;
  744.     new->q1.reg=r;
  745.     new->q2.flags=new->z.flags=0;
  746.     add_IC(new);
  747.     regs[r]=0;
  748. }
  749. void gen_label(int l)
  750. /*  Erzeugt ein Label                                   */
  751. {
  752.     struct IC *new;
  753.     new=(struct IC *)mymalloc(ICS);
  754.     new->code=LABEL;
  755.     new->typf=l;
  756.     new->q1.flags=new->q2.flags=new->z.flags=0;
  757.     add_IC(new);
  758. }
  759. struct obj gen_cond(int m,int l1,int l2)
  760. /*  Generiert code, der 0 oder 1 in Register schreibt   */
  761. {
  762.     struct IC *new;
  763.     struct obj omerk;
  764.     new=(struct IC *)mymalloc(ICS);
  765.     new->code=ASSIGN;
  766.     new->typf=INT;
  767.     new->q1.flags=KONST;
  768.     new->q2.flags=0;
  769.     new->q2.reg=sizetab[INT];
  770.     if(!m) vlong=l2zl(1L); else vlong=l2zl(0L);
  771.     new->q1.val.vint=zl2zi(vlong);
  772.     get_scratch(&new->z,INT,0);
  773.     omerk=new->z;
  774.     add_IC(new);
  775.     new=(struct IC *)mymalloc(ICS);
  776.     new->code=BRA;
  777.     new->typf=l2;
  778.     add_IC(new);
  779.     gen_label(l1);
  780.     new=(struct IC *)mymalloc(ICS);
  781.     new->code=ASSIGN;
  782.     new->typf=INT;
  783.     new->q1.flags=KONST;
  784.     new->q2.flags=0;
  785.     new->q2.reg=sizetab[INT];
  786.     if(!m) vlong=l2zl(0L); else vlong=l2zl(1L);
  787.     new->q1.val.vint=zl2zi(vlong);
  788.     new->z=omerk;
  789. /*    new->z.reg=r;
  790.     new->z.flags=SCRATCH|REG;*/
  791.     add_IC(new);
  792.     gen_label(l2);
  793.     return(omerk);
  794. }
  795. void scratch_var(struct obj *o,int t)
  796. /*  liefert eine temporaere Variable                            */
  797. /*  nicht effizient, aber wer hat schon so wenig Register...    */
  798. {
  799.     struct Typ *nt=(struct Typ *)mymalloc(TYPS);
  800.     if((t&15)<CHAR||(t&15)>POINTER) ierror(0);
  801.     nt->flags=t&31;
  802.     if((t&15)==POINTER){
  803.         nt->next=(struct Typ *)mymalloc(TYPS);
  804.         nt->next->flags=VOID;
  805.         nt->next->next=0;
  806.     }else nt->next=0;
  807.     o->flags=SCRATCH|VAR;o->reg=0;
  808.     o->v=add_var(empty,nt,AUTO,0);
  809.     o->val.vlong=l2zl(0L);
  810. }
  811. void get_scratch(struct obj *o,int t1,int t2)
  812. /*  liefert ein Scratchregister oder eine Scratchvariable       */
  813. {
  814.     if(o->reg=allocreg(t1,t2)){
  815.         o->flags=SCRATCH|REG;
  816.     }else{
  817.         scratch_var(o,t1);
  818.     }
  819. }
  820. void remove_IC(struct IC *p)
  821. /*  entfernt IC p aus Liste */
  822. {
  823.     if(p->prev) p->prev->next=p->next; else first_ic=p->next;
  824.     if(p->next) p->next->prev=p->prev; else last_ic=p->prev;
  825.     if(p->q1.am) free(p->q1.am);
  826.     if(p->q2.am) free(p->q2.am);
  827.     if(p->z.am) free(p->z.am);
  828.     free(p);
  829. }
  830. int do_arith(np p,struct IC *new,np dest,struct obj *o)
  831. /*  erzeugt IC new fuer einen arithmetischen Knoten und speichert das   */
  832. /*  Resultat vom Unterknoten dest in o (fuer a op= b)               */
  833. /*  liefert 0, wenn dest nicht gefunden                             */
  834. {
  835.     int f=0;
  836.     new->code=p->flags;
  837.     if(new->code==PMULT) new->code=MULT;
  838.     gen_IC(p->left,0,0);
  839.     if(dest&&p->left==dest) {*o=p->left->o;f++;}
  840.     gen_IC(p->right,0,0);
  841.     if(dest&&p->right==dest) {*o=p->right->o;f++;}
  842.  
  843.     if((p->left->ntyp->flags&15)==POINTER&&(p->right->ntyp->flags&15)==POINTER){
  844.     /*  Subtrahieren zweier Pointer                                 */
  845.         if(p->flags!=SUB) ierror(0);
  846.         new->typf=INT;
  847.         new->code=SUBPFP;
  848.         new->q1=p->left->o;
  849.         new->q2=p->right->o;
  850.         if(p->left->o.flags&SCRATCH&®ok(p->left->o.reg,INT,0)){
  851.             new->z=p->left->o;
  852.             new->z.flags&=~DREFOBJ;
  853.         }else{
  854.             if(USEQ2ASZ&&(p->right->o.flags&SCRATCH)&®ok(p->right->o.reg,INT,0)){
  855.                 new->z=p->left->o;
  856.                 new->z.flags&=(~DREFOBJ);
  857.             }else{
  858.                 get_scratch(&new->z,INT,0);
  859.             }
  860.         }
  861.         add_IC(new);
  862.         p->o=new->z;
  863.         if(szof(p->left->ntyp->next)>1){
  864.             new=(struct IC *)mymalloc(ICS);
  865.             new->code=DIV;
  866.             new->q1=p->o;
  867.             new->q2.flags=KONST;
  868.             vlong=l2zl((long)szof(p->left->ntyp->next));
  869.             vint=zl2zi(vlong);
  870.             new->q2.val.vint=vint;
  871.             new->z=p->o;
  872.             new->typf=INT;
  873.             add_IC(new);
  874.         }
  875.         return(f);
  876.     }
  877.     if((p->flags==ADD||p->flags==SUB)&&(p->ntyp->flags&15)==POINTER){
  878.     /*  Addieren und Subtrahieren eines Integers zu einem Pointer   */
  879.         if(p->flags==ADD) new->code=ADDI2P; else new->code=SUBIFP;
  880.         new->typf=p->right->ntyp->flags&31;
  881.         new->q1=p->left->o;
  882.         /*  kleinere Typen als MINADDI2P erst in diesen wandeln */
  883.         if((new->typf&15)<MINADDI2P){convert(p->right,/*UNSIGNED|*/MINADDI2P);new->typf=/*UNSIGNED|*/MINADDI2P;}
  884.         new->q2=p->right->o;
  885.         if((p->left->o.flags&SCRATCH)&®ok(new->q1.reg,POINTER,p->left->ntyp->next->flags&31)){
  886.             new->z=p->left->o;
  887.             new->z.flags&=(~DREFOBJ);
  888.         }else{
  889.             get_scratch(&new->z,POINTER,p->left->ntyp->next->flags&31);
  890.         }
  891.         add_IC(new);
  892.         p->o=new->z;
  893.         return(f);
  894.     }
  895.     convert(p->left,p->ntyp->flags&31);
  896.     convert(p->right,p->ntyp->flags&31);
  897.     new->q1=p->left->o;
  898.     new->q2=p->right->o;
  899.     new->typf=p->ntyp->flags&31;
  900.     if((new->q1.flags&SCRATCH)&®ok(new->q1.reg,p->ntyp->flags,0)){
  901.         new->z=new->q1;
  902.         new->z.flags&=~DREFOBJ;
  903.     }else{
  904.         if((new->q2.flags&SCRATCH)&®ok(new->q2.reg,p->ntyp->flags,0)){
  905.             if((p->flags>=OR&&p->flags<=AND)||p->flags==ADD||p->flags==MULT||p->flags==PMULT){
  906.             /*  bei kommutativen Operatoren vertauschen     */
  907.                 new->z=new->q2;
  908.                 new->q2=new->q1;
  909.                 new->q1=new->z;
  910.                 new->z.flags&=~DREFOBJ;
  911.             }else{
  912.                 if(USEQ2ASZ){
  913.                     new->z=new->q2;
  914.                     new->z.flags&=~DREFOBJ;
  915.                 }else{
  916.                     get_scratch(&new->z,new->typf,0);
  917.                 }
  918.             }
  919.         }else{
  920.             get_scratch(&new->z,new->typf,0);
  921.         }
  922.     }
  923.     add_IC(new);
  924.     p->o=new->z;
  925.     return(f);
  926. }
  927.